package com.lutzyt.delivery.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lutzyt.delivery.bean.Commodity;
import com.lutzyt.delivery.bean.Order;
import com.lutzyt.delivery.bean.Shop;
import com.lutzyt.delivery.mapper.ShopDAO;
import com.lutzyt.delivery.service.AddressService;
import com.lutzyt.delivery.service.CommodityService;
import com.lutzyt.delivery.service.OrderService;
import com.lutzyt.delivery.service.ShopService;
import com.lutzyt.delivery.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zyt
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class ShopServiceImpl extends ServiceImpl<ShopDAO, Shop> implements ShopService {

  private ShopDAO shopDAO;
  private AddressService addressService;
  private OrderService orderService;
  private CommodityService commodityService;
  private static final int MAX_HOT_SHOP = 10;

  @Transactional(readOnly = true)
  @Override
  public Shop findById(Integer id) {
    final Shop shop = shopDAO.selectById(id);
    this.setAddress(shop);
    return shop;
  }

  @Transactional(readOnly = true)
  @Override
  public IPage<Shop> findByPage(int pageNum, int pageSize) {
    final Page<Shop> page = shopDAO.selectPage(new Page<>(pageNum, pageSize), null);
    page.getRecords().forEach(this::setAddress);
    log.info("page:{}", page.getRecords());
    return page;
  }

  @Override
  public List<Shop> list() {
    final List<Shop> list = super.list();
    list.forEach(this::setAddress);
    return list;
  }

  /**
   * 设置店铺的地址
   * @param shop
   */
  private void setAddress(Shop shop){
    if (shop.getAddressId()!=null){
      shop.setAddress(addressService.findById(shop.getAddressId()));
    }
  }

  @Override
  public List<Shop> hot() {
    // 本月开始时间
    final Date beginDayOfMonth = DateUtils.getBeginDayOfMonth();
    // 获取订单个数前十的店铺id
    final List<Order> orders = orderService.query()
        .select("shop_id")
        .groupBy("shop_id")
        .orderByDesc("count(shop_id)")
        .ge("create_time", beginDayOfMonth).last("limit "+ MAX_HOT_SHOP).list();
    // 提取出店铺id
    final List<Integer> shopIdList = orders.stream().map(Order::getShopId).collect(Collectors.toList());
    // 查询出店铺信息
    final List<Shop> shops = this.lambdaQuery()
        .in(!shopIdList.isEmpty(),Shop::getId, shopIdList)
        .eq(Shop::getDeleted, 0)
        .last("limit " + MAX_HOT_SHOP)
        .list();
    // 补足剩余的推荐店铺
    if (shops.size() < MAX_HOT_SHOP && !shopIdList.isEmpty()){
      final List<Shop> list = this.lambdaQuery()
          .notIn(Shop::getId, shopIdList)
          .eq(Shop::getDeleted, 0)
          .last("limit " + (MAX_HOT_SHOP - shops.size()))
          .list();
      shops.addAll(list);
    }
    // 设置店铺地址
    shops.forEach(this::setAddress);
    return shops;
  }

  @Override
  public List<Commodity> findCommodityByShopId(String id) {
    final List<Commodity> list = commodityService.lambdaQuery()
        .eq(Commodity::getDeleted, 0)
        .eq(Commodity::getState, "PUT_AWAY")
        .eq(Commodity::getShopId, id).list();
    list.forEach(this::setShopName);
    return list;
  }

  private void setShopName(Commodity commodity){
    final Shop shop = this.findById(commodity.getShopId());;
    commodity.setShopName(shop.getName());
  }

  @Override
  public void insert(Shop shop) {
    shopDAO.insert(shop);
  }

  @Override
  public void update(Shop shop) {
    shopDAO.updateById(shop);
  }

  @Override
  public void deleteById(Integer id) {
    shopDAO.deleteById(id);
  }

  @Override
  public void deleteByIds(List<String> ids) {
    shopDAO.deleteBatchIds(ids);
  }


  @Autowired
  public void setCommodityService(CommodityService commodityService) {
    this.commodityService = commodityService;
  }

  @Autowired
  public void setOrderService(OrderService orderService) {
    this.orderService = orderService;
  }

  @Autowired
  public void setAddressService(AddressService addressService) {
    this.addressService = addressService;
  }

  @Autowired
  public void setShopDAO(ShopDAO shopDAO) {
    this.shopDAO = shopDAO;
  }
}